<?php
//微信转账相关服务

namespace App\Services\Wx;

use EasyWeChat\Pay\Application;

class WxTransfer
{

    public $app;

    private $mainUrl = 'https://api.mch.weixin.qq.com';

    public function __construct()
    {
        $certBasePath = base_path().'/storage/cert/';
        $config = [
            'mch_id'         => env('MCHID'),

            // 商户证书
            'private_key'    => $certBasePath.'apiclient_key.pem',
            'certificate'    => $certBasePath.'apiclient_cert.pem',

            // v3 API 秘钥
            'secret_key'     => env('V3_SECRET_KEY'),

            // v2 API 秘钥
            'v2_secret_key'  => '',

            // 平台证书：微信支付 APIv3 平台证书，需要使用工具下载
            // 下载工具：https://github.com/wechatpay-apiv3/CertificateDownloader
            'platform_certs' => [
                // 请使用绝对路径
                $certBasePath.'platform_cert.pem', //2028-12-06T13:51:49+08:00  todo: 注意！此为到期时间
            ],

            /**
             * 接口请求相关配置，超时时间等，具体可用参数请参考：
             * https://github.com/symfony/symfony/blob/5.3/src/Symfony/Contracts/HttpClient/HttpClientInterface.php
             */
            'http'           => [
                'throw'   => false, // 状态码非 200、300 时是否抛出异常，默认为开启
                'timeout' => 5.0,
                // 'base_uri' => 'https://api.mch.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 uri
            ],
        ];

        $this->app = new Application($config);
    }

    public function getApp()
    {
        return $this->app;
    }


    /**
     * 创建转账单据
     * @param $openid
     * @param $stockId
     * @param $outRequestNo
     * @return array
     * 文档：腾讯内部文档，创建转账单据
     */
    public function createTransferBill(
        $openid,
        $outBillNo,
        $transferSceneId,
        $userName,
        $transferAmount = 0,
        $transferRemark = ''
    ) {
        $url = "/v3/fund-app/mch-transfer/transfer-bills";
        if (app('request')->getHost() == 'api-gbd-coupon.lxi.cloud') { //线上域名
            $notifyUrl = 'https://api-gbd-coupon.lxi.cloud/wx/subsidy/usertransfercallback';
        } else { //测试域名
            $notifyUrl = 'https://wangyizhe.gbd-coupon.lingxi.ren/wx/subsidy/usertransfercallback';
        }
        //用户名敏感信息加密，rsa标准算法
        $userNameEnStr = self::getRiskStrEncrypt($userName);
        if(!$userNameEnStr) {
            return [];
        }
        try {
            $api = $this->app->getClient();
            $body = [
                'appid'             => env('APPID'), //商户AppID
                'out_bill_no'       => $outBillNo, //商户单号 商户系统内部的商家单号，要求此参数只能由数字、大小写字母组成，在商户系统内部唯一
                'transfer_scene_id' => (string) $transferSceneId, //转账场景ID 该批次转账使用的转账场景，可前往“商家转账到零钱-前往功能”中申请。如：1001-现金营销
                'openid'            => $openid,
                'user_name'         => $userNameEnStr,
                //收款方真实姓名。支持标准RSA算法和国密算法，公钥由微信侧提供转账金额 >= 2,000元时，该笔明细必须填写若商户传入收款用户姓名，微信支付会校验用户OpenID与姓名是否一致，并提供电子回单
                'transfer_amount'   => $transferAmount, //转账金额单位为“分”
                'transfer_remark'   => $transferRemark, //单条转账备注（微信用户会收到该备注），UTF8编码，最多允许32个字符
                'notify_url'        => $notifyUrl, //异步接收微信支付结果通知的回调地址，通知url必须为公网可访问的URL，必须为HTTPS，不能携带参数。
            ];
            $res = $api->postJson($url, $body, [
                'headers' => [
                    'Wechatpay-Serial' => '6B382C64C5CA0199376A74504AFDB88C20E70C75',
                ],
            ])->toArray();
        } catch (\Exception $e) {
            return [];
        }

        return $res;
    }

    /**
     * 获取平台证书列表
     * @return array
     */
    public function getPlatFormCertList()
    {
        $url = "v3/certificates";
        try {
            $api = $this->app->getClient();
            $res = $api->get($url)->toArray();
        } catch (\Exception $e) {
            return [];
        }

        return $res;
    }


    /**
     * 敏感词加密，rsa标准算法
     * @param $str
     * @return string
     */
    private static function getRiskStrEncrypt($str)
    {
        //$str是待加密字符串
        $public_key_path = base_path().'/storage/cert/platform_cert.pem';;
        $public_key = file_get_contents($public_key_path);
        $encrypted = '';
        if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)) {
            //base64编码
            $sign = base64_encode($encrypted);
        } else {
            return '';
        }
        return $sign;
    }

    /**
     * 查询转账单据状态
     * @param $outBillNo
     * @return array
     */
    public function getTransferBillInfo($outBillNo)
    {
        $url = "/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{$outBillNo}";
        try {
            $api = $this->app->getClient();
            $res = $api->get($url)->toArray();
        } catch (\Exception $e) {
            return [];
        }

        return $res;
    }


}
